﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace QD.Tools
{
    public static class ObjectHelper
    {
        /// <summary>
        /// 根据T的属性初始化一个DataTable
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static DataTable ToDataTable<T>() where T : new()
        {
            T t = new T();
            DataTable dt = new DataTable();
            PropertyInfo[] infos = t.GetType().GetProperties();
            foreach (PropertyInfo info in infos)
            {
                if ((info.PropertyType.IsValueType || info.PropertyType == typeof(string)))
                {
                    DataColumn col;
                    Type type = null;
                    if (info.PropertyType.IsGenericType)
                    {
                        NullableConverter nullableConverter = new NullableConverter(info.PropertyType);
                        type = nullableConverter.UnderlyingType;

                        col = new DataColumn(info.Name, type);
                        col.AllowDBNull = true;
                    }
                    else
                    {
                        type = info.PropertyType;
                        col = new DataColumn(info.Name, type);
                    }
                    dt.Columns.Add(col);
                }
            }
            return dt;
        }


        /// <summary>
        /// 根据obj初始化一个DataTable
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static DataTable ToDataTable(this object obj)
        {
            return ToDataTable(obj,true);
        }

        /// <summary>
        /// 根据obj初始化一个DataTable
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static DataTable ToDataTable(this object obj, bool isAddNewRow)
        {
            DataTable dt = new DataTable();
            PropertyInfo[] infos = obj.GetType().GetProperties();
            foreach (PropertyInfo info in infos)
            {
                if ((info.PropertyType.IsValueType || info.PropertyType == typeof(string)))
                {
                    DataColumn col;
                    Type type = null;
                    if (info.PropertyType.IsGenericType)
                    {
                        NullableConverter nullableConverter = new NullableConverter(info.PropertyType);
                        type = nullableConverter.UnderlyingType;

                        col = new DataColumn(info.Name, type);
                        col.AllowDBNull = true;
                    }
                    else
                    {
                        type = info.PropertyType;
                        col = new DataColumn(info.Name, type);
                    }

                    dt.Columns.Add(col);
                }
                else if (info.PropertyType == typeof(Byte[]))
                {
                    dt.Columns.Add(info.Name, typeof(Byte[]));
                }
            }
            if (isAddNewRow)
            {
                DataRow dr = dt.NewRow();
                foreach (PropertyInfo info in infos)
                {
                    if ((info.PropertyType.IsValueType || info.PropertyType == typeof(string)))
                    {
                        object value = info.GetValue(obj, null);
                        if (value == null)
                        {
                            value = DBNull.Value;
                        }
                        dr[info.Name] = value;
                    }
                }
                dt.Rows.Add(dr);
            }
            return dt;
        }

        /// <summary>
        /// 将IList集合转为DataTable，不能返回null，因为DataGridView的数据源如果为null,后面操作会出问题
        /// </summary>
        public static DataTable ToDataTable(this List<object> objList, object obj)
        {
            DataTable dt = new DataTable();
            PropertyInfo[] pInfos = obj.GetType().GetProperties();
            foreach (PropertyInfo info in pInfos)
            {
                if (info.PropertyType.IsValueType || info.PropertyType == typeof(string))
                {
                    DataColumn col;
                    Type type = null;
                    if (info.PropertyType.IsGenericType)
                    {
                        NullableConverter nullableConverter = new NullableConverter(info.PropertyType);
                        type = nullableConverter.UnderlyingType;

                        col = new DataColumn(info.Name, type);
                        col.AllowDBNull = true;
                    }
                    else
                    {
                        type = info.PropertyType;
                        col = new DataColumn(info.Name, type);
                    }

                    dt.Columns.Add(col);
                }
            }

            foreach (object obj1 in objList)
            {
                DataRow dr = dt.NewRow();
                foreach (PropertyInfo info in obj1.GetType().GetProperties())
                {
                    if (info.PropertyType.IsValueType || info.PropertyType == typeof(string))
                    {
                        object value = info.GetValue(obj1, null);
                        if (value == null)
                        {
                            value = DBNull.Value;
                        }
                        dr[info.Name] = value;
                    }
                }
                dt.Rows.Add(dr);
            }

            // dt.AcceptChanges()这行代码必须要加，不然将dt绑定到DataGridView上后，再取DataGridView上的数据，行状态都是Added
            dt.AcceptChanges();
            return dt;
        }
    }
}
